//
//  SegmentLineChartView.swift
//  MYModule
//
//  Created by 李然 on 2022/7/25.
//

import UIKit
import RxCocoa
import RxSwift

public struct SegmentLineChartModel: Equatable {
    public var total:Double
    public let type:Int
    
    public init(total:Double,type:Int){
        self.total = total
        self.type = type
    }
    
    public static func == (lhs: Self, rhs: Self) -> Bool {
        
       return lhs.type == rhs.type && lhs.total == rhs.total
        
    }
}

public class SegmentLineChartView: UIView {
    
    public let selectIndex = PublishSubject<Int>()
    private var _index:Int?
    
    public var data:[SegmentLineChartModel] = [] {
        
        didSet {
            
            self.setNeedsDisplay()
            
        }
        
    }
    
    public var colors:[UIColor?] = []
    
    public var lineCount = 4    //type类型数量，图标在Y轴的数量
    public var highlightEnable = false
    
    private var highlightViews:[UIView] = []
    
    public func setTouchLocation(_ point:CGPoint,inView view:UIView){
        for (index,barView) in self.highlightViews.enumerated() {
            let frame = barView.convert(barView.bounds, from: view)
            let x = -frame.origin.x
            let width = frame.size.width
            if point.x > x && point.x < x + width{
                guard _index != index else {
                    return
                }
                if let oldIndex = _index{
                    self.highlightViews[oldIndex].isHidden = true
                }
                barView.isHidden = false
                _index = index
                selectIndex.onNext(index)
                break
            }
        }
    }
    
    public func clearHighlight() {
        _index = nil
        setBarViewHidden()
    }
    
    public func setBarViewHidden(){
        self.highlightViews.forEach{$0.isHidden = true}
    }
    
    public override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        self.subviews.forEach{$0.removeFromSuperview()}
        self.layer.sublayers?.forEach{$0.removeFromSuperlayer()}
        
        self.highlightViews.forEach{$0.removeFromSuperview()}
        self.highlightViews = []
        
        guard !self.data.isEmpty else { return }
        guard !self.colors.isEmpty else { return }
        guard lineCount > 1 else { return }
        guard self.colors.count == lineCount else {
        
            fatalError("SegmentLineChartView 的渐变颜色值不等于lineCount")
            
        }
       
        let totalCount = self.data.reduce(0, { $0 + ($1.total ) })
        
        guard totalCount > 0 else {return}
        
        let container = UIView(frame: rect)
        
        let strackRate = rect.width / CGFloat(totalCount)
        let rateHeight = rect.height / 5
        let gapHeight = rateHeight / 3.0
        
        var lastType = 0
        var lastWidth: CGFloat = 0
        
        var strackX = 0.0
        let cornerRadiux: CGFloat = 5
        
        for i in 0 ..< data.count {
            
            let value = data[i]
            let subTotal = value.total
            let width = subTotal*strackRate
            
//            if width <= 2 {
//                continue
//            }
          
            let myFrameY = Double(value.type) * (rateHeight + gapHeight)
            var myFrame = CGRect(x: strackX, y: myFrameY, width: width, height: rateHeight)
            var barFrame = CGRect(x: strackX, y: myFrameY + rateHeight, width: width, height: height - (myFrameY + rateHeight))
            if i > 0{
                myFrame = CGRect(x: strackX - 1, y: myFrameY, width: width + 1, height: rateHeight)
                barFrame = CGRect(x: strackX - 1, y: myFrameY + rateHeight, width: width + 1, height: height - (myFrameY + rateHeight))
            }
            
            
            let partView = UIView(frame: myFrame)
            
            if i == 0 {
                let mask: UIBezierPath = UIBezierPath(roundedRect: partView.bounds, byRoundingCorners: [.topRight,.bottomRight], cornerRadii: CGSize(width: cornerRadiux, height: cornerRadiux))
                let maskLayer = CAShapeLayer()
                maskLayer.frame = partView.bounds
                maskLayer.path = mask.cgPath
                partView.layer.mask = maskLayer
            }else if i == data.count - 1 {
                let mask: UIBezierPath = UIBezierPath(roundedRect: partView.bounds, byRoundingCorners: [.topLeft,.bottomLeft], cornerRadii: CGSize(width: cornerRadiux, height: cornerRadiux))
                let maskLayer = CAShapeLayer()
                maskLayer.frame = partView.bounds
                maskLayer.path = mask.cgPath
                partView.layer.mask = maskLayer
            }else {
                
                partView.layer.masksToBounds = true
                partView.layer.cornerRadius = cornerRadiux
                
            }
            
            partView.backgroundColor = UIColor.black
            
            let barView = UIView(frame: barFrame)
            let barViewColor = self.colors.count > value.type ? self.colors[value.type] : .clear
            barView.backgroundColor = barViewColor?.withAlphaComponent(0.2)
            barView.isHidden = true
            container.addSubview(barView)
            self.highlightViews.append(barView)
            
            let currentType = value.type
            container.addSubview(partView)
            
            var currentTop = cornerRadiux
            var lastTop = cornerRadiux
            if CGFloat(width / 2.0) < cornerRadiux {
                currentTop = CGFloat(width / 2.0) + 0.5
            }
            if i > 0 {
                if CGFloat(lastWidth / 2.0) < cornerRadiux {
                    lastTop = CGFloat(lastWidth / 2.0) - 0.5
                }
                if currentType > lastType {
                    let lineView = UIView(frame: CGRect(x: strackX - 1, y: Double(lastType + 1) * (rateHeight + gapHeight) - gapHeight * 2, width: 1, height: Double(currentType - lastType) * (rateHeight + gapHeight)))
                    let trianglePath = UIBezierPath()
                    var point = CGPoint(x: 0.5, y: CGFloat(gapHeight) - cornerRadiux)
                    trianglePath.move(to: point)
                    point = CGPoint(x:  -lastTop, y: CGFloat(gapHeight))
                    trianglePath.addLine(to: point)
                    point = CGPoint(x: 0.5, y: CGFloat(gapHeight) + cornerRadiux)
                    var controlPoint = CGPoint(x: 0.5, y: CGFloat(gapHeight))
                    trianglePath.addQuadCurve(to: point, controlPoint: controlPoint)
                    trianglePath.close()
                    let triangleLayer = CAShapeLayer()
                    triangleLayer.path = trianglePath.cgPath
                    triangleLayer.fillColor = UIColor.black.cgColor
                    lineView.layer.addSublayer(triangleLayer)
                    
                    let trianglePath2 = UIBezierPath()
                    point = CGPoint(x: 0.5, y: lineView.height - 2 * CGFloat(gapHeight) + cornerRadiux)
                    trianglePath2.move(to: point)
                    point = CGPoint(x:  currentTop, y: lineView.height - 2 * CGFloat(gapHeight))
                    trianglePath2.addLine(to: point)
                    point = CGPoint(x: 0.5, y: lineView.height - 2 * CGFloat(gapHeight) - cornerRadiux)
                    controlPoint = CGPoint(x: 0.5, y: lineView.height - 2 * CGFloat(gapHeight))
                    trianglePath2.addQuadCurve(to: point, controlPoint: controlPoint)
                    trianglePath.close()
                    let triangleLayer2 = CAShapeLayer()
                    triangleLayer2.path = trianglePath2.cgPath
                    triangleLayer2.fillColor = UIColor.black.cgColor
                    lineView.layer.addSublayer(triangleLayer2)
                    
                    lineView.backgroundColor = UIColor.black
                    container.addSubview(lineView)
                    
                } else {
                    
                    let lineView = UIView(frame: CGRect(x: strackX - 1, y: myFrameY + gapHeight, width: 1, height: Double(lastType - currentType) * (rateHeight + gapHeight)))
                    
                    let trianglePath = UIBezierPath()
                    var point = CGPoint(x: 0.5, y: 2 * CGFloat(gapHeight) - cornerRadiux)
                    trianglePath.move(to: point)
                    point = CGPoint(x:  currentTop, y: 2 * CGFloat(gapHeight))
                    trianglePath.addLine(to: point)
                    point = CGPoint(x: 0.5, y: 2 * CGFloat(gapHeight) + cornerRadiux)
                    var controlPoint = CGPoint(x: 0.5, y: 2 * CGFloat(gapHeight))
                    trianglePath.addQuadCurve(to: point, controlPoint: controlPoint)
                    trianglePath.close()
                    let triangleLayer = CAShapeLayer()
                    triangleLayer.path = trianglePath.cgPath
                    triangleLayer.fillColor = UIColor.black.cgColor
                    lineView.layer.addSublayer(triangleLayer)
                    
                    let trianglePath2 = UIBezierPath()
                    point = CGPoint(x: 0.5, y: lineView.height - CGFloat(gapHeight) + cornerRadiux)
                    trianglePath2.move(to: point)
                    point = CGPoint(x:  -lastTop , y: lineView.height - CGFloat(gapHeight))
                    trianglePath2.addLine(to: point)
                    point = CGPoint(x: 0.5, y: lineView.height - CGFloat(gapHeight) - cornerRadiux)
                    controlPoint = CGPoint(x: 0.5, y: lineView.height - CGFloat(gapHeight))
                    trianglePath2.addQuadCurve(to: point, controlPoint: controlPoint)
                    trianglePath.close()
                    let triangleLayer2 = CAShapeLayer()
                    triangleLayer2.path = trianglePath2.cgPath
                    triangleLayer2.fillColor = UIColor.black.cgColor
                    lineView.layer.addSublayer(triangleLayer2)
                    
                    
                    lineView.backgroundColor = UIColor.black
                    container.addSubview(lineView)
                }
            }
            
            strackX += width
            lastType = currentType
            lastWidth = CGFloat(width)
        }
        
        var gradientLocations:[NSNumber] = []
        let t = Double(1/Double(lineCount-1))
        for i in 0..<lineCount{
            gradientLocations.append(NSNumber.init(value: Double(i) * t))
        }
        
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = self.colors.compactMap{$0?.cgColor}
        gradientLayer.locations = gradientLocations
        gradientLayer.frame = rect
        let maskView = UIView(frame: rect)
        self.addSubview(maskView)
        maskView.layer.insertSublayer(gradientLayer, at: 0)
        maskView.mask = container
    }
    
    
 
}
